package com.atguigu.tingshu.search.listener;

import com.atguigu.tingshu.album.client.AlbumInfoFeignClient;
import com.atguigu.tingshu.album.client.CategoryFeignClient;
import com.atguigu.tingshu.common.constant.TingShuMqConstants;
import com.atguigu.tingshu.common.result.Result;
import com.atguigu.tingshu.common.util.PinYinUtils;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.model.album.BaseCategoryView;
import com.atguigu.tingshu.model.search.AlbumInfoIndex;
import com.atguigu.tingshu.model.search.AttributeValueIndex;
import com.atguigu.tingshu.model.search.SuggestIndex;
import com.atguigu.tingshu.vo.base.user.UserInfo;
import com.atguigu.tingshu.user.client.UserInfoFeignClient;
import com.atguigu.tingshu.vo.album.AlbumListVo;
import com.rabbitmq.client.Channel;
import jakarta.annotation.Resource;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.BeanUtils;
import org.springframework.data.elasticsearch.client.elc.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.suggest.Completion;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import java.io.IOException;
import java.util.Collections;
import java.util.Random;

@Component
public class AlbumListener {
    @Resource
    private ElasticsearchTemplate elasticsearchTemplate;
    @Resource
    private AlbumInfoFeignClient albumInfoFeignClient;
    @Resource
    private UserInfoFeignClient userInfoFeignClient;
    @Resource
    private CategoryFeignClient categoryFeignClient;

    @RabbitListener(bindings = @QueueBinding(
            exchange = @Exchange(value = TingShuMqConstants.ALBUM_EXCHANGE, type = ExchangeTypes.TOPIC, ignoreDeclarationExceptions = "true"),
            value = @Queue(value = TingShuMqConstants.ALBUM_SAVE_UPDATE_QUEUE),
            key = TingShuMqConstants.ALBUM_SAVE_UPDATE_RK
    ))
    public void saveOrUpdateAlbum(Long albumId, Channel channel, Message message) throws IOException {
        if (albumId == null) {
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        }
        Result<AlbumListVo> userAlbumR = albumInfoFeignClient.findUserAlbum(albumId);
        Assert.notNull(userAlbumR, "实时同步数据时，查询专辑信息失败！");
        AlbumListVo albumListVo = userAlbumR.getData();
        if (albumListVo != null) {
            AlbumInfoIndex albumInfoIndex = new AlbumInfoIndex();
            BeanUtils.copyProperties(albumListVo, albumInfoIndex);
            albumInfoIndex.setId(albumListVo.getAlbumId());

            //2、根据userId查询用户信息
            Result<UserInfo> userInfoR = userInfoFeignClient.getUserInfo(albumListVo.getUserId());
            Assert.notNull(userInfoR, "实时同步数据时，获取用户信息失败！");
            UserInfo userInfo = userInfoR.getData();
            if (userInfo != null) {
                albumInfoIndex.setAnnouncerName(userInfo.getNickname());
            }
            //3、根据第三级分类id获取三级id
            Result<BaseCategoryView> baseCategoryViewR = categoryFeignClient.findBaseCategoryView(albumListVo.getCategory3Id());
            Assert.notNull(baseCategoryViewR, "实时同步数据时，获取三级分类数据信息失败！");
            BaseCategoryView categoryView = baseCategoryViewR.getData();
            if (categoryView != null) {
                albumInfoIndex.setCategory1Id(categoryView.getCategory1Id());
                albumInfoIndex.setCategory2Id(categoryView.getCategory2Id());
            }
            albumInfoIndex.setPlayStatNum((new Random().nextInt(10) + 1) * 10000000);
            albumInfoIndex.setSubscribeStatNum((new Random().nextInt(10) + 1) * 10000000);
            albumInfoIndex.setBuyStatNum((new Random().nextInt(10) + 1) * 10000000);
            albumInfoIndex.setCommentStatNum((new Random().nextInt(10) + 1) * 10000000);
            albumInfoIndex.setHotScore(albumInfoIndex.getPlayStatNum() * 0.1 + albumInfoIndex.getCommentStatNum() * 0.2 + albumInfoIndex.getCommentStatNum() * 0.3 + albumInfoIndex.getBuyStatNum() * 0.4);
            //4、根据专辑id获取专辑属性值列表
            Result<AlbumInfo> albumInfoR = albumInfoFeignClient.getAlbumInfo(albumListVo.getAlbumId());
            Assert.notNull(albumInfoR, "实时同步数据时，获取专辑失败！");
            albumInfoIndex.setAttributeValueIndexList(albumInfoR.getData().getAlbumAttributeValueVoList().stream().map(albumAttributeValue -> {
                AttributeValueIndex attributeValueIndex = new AttributeValueIndex();
                BeanUtils.copyProperties(albumAttributeValue, attributeValueIndex);
                return attributeValueIndex;
            }).toList());
            elasticsearchTemplate.save(albumInfoIndex);
            ///5、保存专辑标题的搜索建议
            //5.1、标题匹配
            SuggestIndex titleSuggestIndex = new SuggestIndex();
            titleSuggestIndex.setId("title" + albumInfoIndex.getId().toString());
            titleSuggestIndex.setTitle(albumInfoIndex.getAlbumTitle());
            titleSuggestIndex.setKeyword(new Completion(Collections.singletonList(albumInfoIndex.getAlbumTitle())));
            titleSuggestIndex.setKeywordPinyin(new Completion(Collections.singletonList(PinYinUtils.toHanyuPinyin(albumInfoIndex.getAlbumTitle()))));
            titleSuggestIndex.setKeywordSequence(new Completion(Collections.singletonList(PinYinUtils.getFirstLetter(albumInfoIndex.getAlbumTitle()))));
            elasticsearchTemplate.save(titleSuggestIndex);
            //5.2、简介匹配
            SuggestIndex introSuggestIndex = new SuggestIndex();
            introSuggestIndex.setId("intro" + albumInfoIndex.getId().toString());
            introSuggestIndex.setTitle(albumInfoIndex.getAlbumIntro());
            introSuggestIndex.setKeyword(new Completion(Collections.singletonList(albumInfoIndex.getAlbumIntro())));
            introSuggestIndex.setKeywordPinyin(new Completion(Collections.singletonList(PinYinUtils.toHanyuPinyin(albumInfoIndex.getAlbumIntro()))));
            introSuggestIndex.setKeywordSequence(new Completion(Collections.singletonList(PinYinUtils.getFirstLetter(albumInfoIndex.getAlbumIntro()))));
            elasticsearchTemplate.save(introSuggestIndex);
            //5.3、主播名匹配
            if (albumInfoIndex.getAnnouncerName() != null) {
                SuggestIndex announcerNameSuggestIndex = new SuggestIndex();
                announcerNameSuggestIndex.setId("announcerName" + albumInfoIndex.getId().toString());
                announcerNameSuggestIndex.setTitle(albumInfoIndex.getAnnouncerName());
                announcerNameSuggestIndex.setKeyword(new Completion(Collections.singletonList(albumInfoIndex.getAnnouncerName())));
                announcerNameSuggestIndex.setKeywordPinyin(new Completion(Collections.singletonList(PinYinUtils.toHanyuPinyin(albumInfoIndex.getAnnouncerName()))));
                announcerNameSuggestIndex.setKeywordSequence(new Completion(Collections.singletonList(PinYinUtils.getFirstLetter(albumInfoIndex.getAnnouncerName()))));
                elasticsearchTemplate.save(announcerNameSuggestIndex);
            }
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        }
    }

    @RabbitListener(bindings = @QueueBinding(
            exchange = @Exchange(value = TingShuMqConstants.ALBUM_EXCHANGE, type = ExchangeTypes.TOPIC, ignoreDeclarationExceptions = "true"),
            value = @Queue(value = TingShuMqConstants.ALBUM_DELETE_QUEUE),
            key = TingShuMqConstants.ALBUM_DELETE_RK
    ))
    public void deleteAlbum(Long albumId, Channel channel, Message message) throws IOException {
        //TODO: 删除专辑信息
        if (albumId != null) {
            elasticsearchTemplate.delete(albumId.toString(), AlbumInfoIndex.class);
            elasticsearchTemplate.delete(albumId.toString(), SuggestIndex.class);
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        }
        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
    }
}
